#include "gui/formlayout.h"

#include <algorithm>
#include <functional>
#include <numeric>

void FormLayout::Arrange(Widget* parent){
    std::vector<Widget*> children = parent->GetChildren();
    std::vector<Widget*> left_items;
    std::vector<Widget*> right_items;

    for(unsigned int i=0; i<children.size(); i++){
        if((i%2) == 0){
            left_items.push_back(children.at(i));
        }
        else{
            right_items.push_back(children.at(i));
        }
    }
    Arrange(parent, left_items, right_items);
}


void FormLayout::Arrange(Widget* parent, std::vector<Widget*> left_items, std::vector<Widget*> right_items){
    auto FindMax = [](std::vector<Widget*> items){
        int max = 0;
        for(Widget* item : items){
            int width = item->GetWidth();
            max = width > max ? width : max;
        }
        return max;
    };

    auto GetRowHeights = [](std::vector<Widget*> left_items, std::vector<Widget*> right_items){
        std::vector<int> heights;
        for(unsigned int i = 0; i<left_items.size(); i++){
            int left_height = left_items.at(i)->GetHeight();
            int right_height = right_items.at(i)->GetHeight();
            heights.push_back( right_height > left_height ? right_height : left_height);
        }
        return heights;
    };

    auto SetPositions = [padding](std::vector<Widget*> items, int xoff, int yoff){
        for(Widget* item : items){
            item->Setx(xoff);
            item->Sety(yoff);
            yoff = yoff - padding - item->GetHeight();
        }
    };

    if(left_items.size() > right_items.size()){
        left_items.resize(right_items.size());
        std::cout<<"WARNING: Dropping children from form layout\n";
    }
    else if(left_items.size() < right_items.size()){
        right_items.resize(left_items.size());
        std::cout<<"WARNING: Dropping children from form layout\n";
    }

    int xoff = border;
    int yoff = -border;

    int left_max = FindMax(left_items);
    int right_max = FindMax(right_items);

    std::vector<int> heights = GetRowHeights(left_items, right_items);

    SetPositions(left_items, xoff, yoff);
    SetPositions(right_items, xoff + left_max + padding, yoff);

    parent->SetWidth(left_max + right_max + border*2 + padding);
    parent->SetHeight(std::accumulate(heights.begin(), heights.end(), heights.size()*padding + border*2));
}
